﻿using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine.UIElements;

namespace DA.AnimGraph.Editor {

    [NodeMenuItem(typeof(AGANode_BlendSpace1D), "Blend Space 1D")]
    internal class NodeView_BlendSpace1D : NodeViewBase {
        public override string titleText => "Blend Space 1D";
        protected override NodeViewInspectorSourceBase dataSource => inspectorData;
        NodeViewInspector_BlendSpace1D inspectorData;

        internal override void Init(AGAHandle_Node handle, AnimGraphView graphView, AGEEnvironment ageContext) {
            inspectorData = new NodeViewInspector_BlendSpace1D();
            inspectorData.SetHandle(handle);
            base.Init(handle, graphView, ageContext);
        }
    }


    internal class NodeViewInspector_BlendSpace1D : NodeViewInspectorSourceBase {

        [InspectorField] public AGAFieldModel_FloatLink inputPosition;

        [InspectorField(tag: "clips", isList: true)]
        public List<AGAFieldModel_BlendSpace1DClip> clips;

        [InspectorField] public Action sort;
        protected override void LoadFromModel() {
            var model = handleKeeper.handle.data.modelProperty as AGANodeModel_BlendSpace1D;
            clips = model.clips;
            inputPosition = model.inputPosition;

            sort = Sort;
        }
        protected override void SaveToModel() {
            handleKeeper.handle.SetDirty();
            var listView = inspectorWidgets["clips"] as ListViewAGE;
            listView?.Rebuild();
        }
        public void Sort() {
            clips.Sort((x, y) => {
                return x.position.CompareTo(y.position);
            });
            var listView = inspectorWidgets["clips"] as ListViewAGE;
            listView.Rebuild();
        }

        protected override VisualElement CustomizeField(string name, InspectorFieldAttribute fieldAttribute, FieldInfo fieldInfo, AGEContext ageContext, Action inspectorChangeCallback) {
            if (fieldAttribute.tag == "clips") {
                return BuildClipListView(name, fieldAttribute, fieldInfo, ageContext, inspectorChangeCallback);
            }
            return base.CustomizeField(name, fieldAttribute, fieldInfo, ageContext, inspectorChangeCallback);
        }
        VisualElement BuildClipListView(string name, InspectorFieldAttribute fieldAttribute, FieldInfo fieldInfo, AGEContext ageContext, Action inspectorChangeCallback) {
            var listView = new ListViewAGE() {
                title = name,
                enableCountController = true,
                itemsSource = clips,
            };
            listView.makeItem = () => {
                var w = new FoldoutWrapper();
                w.deleteButtonClicked += (index) => {
                   clips.RemoveAt(index);
                   inspectorChangeCallback?.Invoke();
                };
                var l = new InspectorField_BS1DClip();
                return (l, w);
            };
            listView.bindItem = (element, wrapper, index) => {
                if (element is InspectorField_BS1DClip field) {
                    field.Init(null, clips[index], ageContext, inspectorChangeCallback);
                }
                if (wrapper is FoldoutWrapper w) {
                    w.index = index;
                    w.text = $"[{index}]";
                    w.enableDelete = true;
                }
            };
            listView.addButtonClicked = () => {
                clips.Add(new AGAFieldModel_BlendSpace1DClip());
                inspectorChangeCallback?.Invoke();
            };
            return listView;
        }

        class InspectorField_BS1DClip : InspectorField<AGAFieldModel_BlendSpace1DClip> {

            InspectorField_ClipLink clipField;
            FloatField positionField;

            protected override void BuildUI() {
                clipField = new InspectorField_ClipLink();
                clipField.Init("clip", source.clip, ageContext, OnChanged);

                positionField = new FloatField("position");
                positionField.value = source.position;
                positionField.RegisterCallback<FocusOutEvent>(evt => OnChanged());
            }
            protected override void DrawUI() {
                Add(clipField);
                Add(positionField);
            }
            private void OnChanged() {
                source.position = positionField.value;

                inspectorChangeCallback?.Invoke();
            }
        }
    }


}
